home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / nt / source.exe / POSIX / ELVIS / PC.C < prev    next >
C/C++ Source or Header  |  1992-09-26  |  6KB  |  271 lines

  1. /* pc.c */
  2.  
  3. /* Author:
  4.  *    Guntram Blohm
  5.  *    Buchenstrasse 19
  6.  *    7904 Erbach, West Germany
  7.  *    Tel. ++49-7305-6997
  8.  *    sorry - no regular network connection
  9.  */
  10.  
  11. /* This file implements the ibm pc bios interface. See IBM documentation
  12.  * for details.
  13.  * If TERM is set upon invocation of elvis, this code is ignored completely,
  14.  * and the standard termcap functions are used, thus, even not-so-close
  15.  * compatibles can run elvis. For close compatibles however, bios output
  16.  * is much faster (and permits reverse scrolling, adding and deleting lines,
  17.  * and much more ansi.sys isn't capable of). GB.
  18.  */
  19.  
  20. #include "config.h"
  21. #include "vi.h"
  22.  
  23. #if MSDOS
  24.  
  25. #include <dos.h>
  26.  
  27. static void video();
  28.  
  29. /* vmode contains the screen attribute index and is set by attrset.*/
  30.  
  31. int vmode;
  32.  
  33. /* The following array contains attribute definitions for
  34.  * color/monochrome attributes. Screen selects one of the sets.
  35.  * Maybe i'll put them into elvis options one day.
  36.  */
  37.  
  38. static int screen;
  39. static char attr[2][5] =
  40. {
  41.     /*    :se:    :so:    :VB:    :ul:    :as:    */
  42.     {    0x1f,    0x1d,    0x1e,    0x1a,    0x1c,    },    /* color */
  43.     {    0x07,    0x70,    0x0f,    0x01,    0x0f,    },    /* monochrome */
  44. };
  45.  
  46. /*
  47.  * bios interface functions for elvis - pc version
  48.  */
  49.  
  50. /* cursor up: determine current position, decrement row, set position */
  51.  
  52. void v_up()
  53. {
  54.     int dx;
  55.     video(0x300,(int *)0,&dx);
  56.     dx-=0x100;
  57.     video(0x200,(int *)0,&dx);
  58. }
  59.  
  60. #ifndef NO_CURSORSHAPE
  61. /* cursor big: set begin scan to end scan - 4 */
  62. void v_cb()
  63. {
  64.     int cx;
  65.     video(0x300, &cx, (int *)0);
  66.     cx=((cx&0xff)|(((cx&0xff)-4)<<8));
  67.     video(0x100, &cx, (int *)0);
  68. }
  69.  
  70. /* cursor small: set begin scan to end scan - 1 */
  71. void v_cs()
  72. {
  73.     int cx;
  74.     video(0x300, &cx, (int *)0);
  75.     cx=((cx&0xff)|(((cx&0xff)-1)<<8));
  76.     video(0x100, &cx, (int *)0);
  77. }
  78. #endif
  79.  
  80. /* clear to end: get cursor position and emit the aproppriate number
  81.  * of spaces, without moving cursor.
  82.  */
  83.  
  84. void v_ce()
  85. {
  86.     int cx, dx;
  87.     video(0x300,(int *)0,&dx);
  88.     cx=COLS-(dx&0xff);
  89.     video(0x920,&cx,(int *)0);
  90. }
  91.  
  92. /* clear screen: clear all and set cursor home */
  93.  
  94. void v_cl()
  95. {
  96.     int cx=0, dx=((LINES-1)<<8)+COLS-1;
  97.     video(0x0600,&cx,&dx);
  98.     dx=0;
  99.     video(0x0200,&cx,&dx);
  100. }
  101.  
  102. /* clear to bottom: get position, clear to eol, clear next line to end */
  103.  
  104. void v_cd()
  105. {
  106.     int cx, dx, dxtmp;
  107.     video(0x0300,(int *)0,&dx);
  108.     dxtmp=(dx&0xff00)|(COLS-1);
  109.     cx=dx;
  110.     video(0x0600,&cx,&dxtmp);
  111.     cx=(dx&0xff00)+0x100;
  112.     dx=((LINES-1)<<8)+COLS-1;
  113.     video(0x600,&cx,&dx);
  114. }
  115.  
  116. /* add line: scroll rest of screen down */
  117.  
  118. void v_al()
  119. {
  120.     int cx,dx;
  121.     video(0x0300,(int *)0,&dx);
  122.     cx=(dx&0xff00);
  123.     dx=((LINES-1)<<8)+COLS-1;
  124.     video(0x701,&cx,&dx);
  125. }
  126.  
  127. /* delete line: scroll rest up */
  128.  
  129. void v_dl()
  130. {
  131.     int cx,dx;
  132.     video(0x0300,(int *)0,&dx);
  133.     cx=(dx&0xff00)/*+0x100*/;
  134.     dx=((LINES-1)<<8)+COLS-1;
  135.     video(0x601,&cx,&dx);
  136. }
  137.  
  138. /* scroll reverse: scroll whole screen */
  139.  
  140. void v_sr()
  141. {
  142.     int cx=0, dx=((LINES-1)<<8)+COLS-1;
  143.     video(0x0701,&cx,&dx);
  144. }
  145.  
  146. /* set cursor */
  147.  
  148. void v_move(x,y)
  149.     int x, y;
  150. {
  151.     int dx=(y<<8)+x;
  152.     video(0x200,(int *)0,&dx);
  153. }
  154.  
  155. /* put character: set attribute first, then execute char.
  156.  * Also remember if current line has changed.
  157.  */
  158.  
  159. int v_put(ch)
  160.     int ch;
  161. {
  162.     int cx=1;
  163.     ch&=0xff;
  164.     if (ch>=' ')
  165.         video(0x900|ch,&cx,(int *)0);
  166.     video(0xe00|ch,(int *)0, (int *)0);
  167.     if (ch=='\n')
  168.     {    exwrote = TRUE;
  169.         video(0xe0d, (int *)0, (int *)0);
  170.     }
  171.     return ch;
  172. }
  173.  
  174. /* determine number of screen columns. Also set attrset according
  175.  * to monochrome/color screen.
  176.  */
  177.  
  178. int v_cols()
  179. {
  180.     union REGS regs;
  181.     regs.h.ah=0x0f;
  182.     int86(0x10, ®s, ®s);
  183.     if (regs.h.al==7)            /* monochrome mode ? */
  184.         screen=1;
  185.     else
  186.         screen=0;
  187.     return regs.h.ah;
  188. }
  189.  
  190. /* Getting the number of rows is hard. Most screens support 25 only,
  191.  * EGA/VGA also support 43/50 lines, and some OEM's even more.
  192.  * Unfortunately, there is no standard bios variable for the number
  193.  * of lines, and the bios screen memory size is always rounded up
  194.  * to 0x1000. So, we'll really have to cheat.
  195.  * When using the screen memory size, keep in mind that each character
  196.  * byte has an associated attribute byte.
  197.  *
  198.  * uses:    word at 40:4c contains    memory size
  199.  *        byte at 40:84         # of rows-1 (sometimes)
  200.  *        byte at    40:4a        # of columns
  201.  */
  202.  
  203. int v_rows()
  204. {
  205.     int line, oldline;
  206.  
  207.     /* screen size less then 4K? then we have 25 lines only */
  208.  
  209.     if (*(int far *)(0x0040004cl)<=4096)
  210.         return 25;
  211.  
  212.     /* VEGA vga uses the bios byte at 0x40:0x84 for # of rows.
  213.      * Use that byte, if it makes sense together with memory size.
  214.      */
  215.  
  216.     if ((((*(unsigned char far *)(0x0040004aL)*2*
  217.         (*(unsigned char far *)(0x00400084L)+1))+0xfff)&(~0xfff))==
  218.         *(unsigned int far *)(0x0040004cL))
  219.             return *(unsigned char far *)(0x00400084L)+1;
  220.  
  221.     /* uh oh. Emit '\n's until screen starts scrolling. */
  222.  
  223.     v_move(oldline=0, 0);
  224.     for (;;)
  225.     {
  226.         video(0xe0a,(int *)0,(int *)0);
  227.         video(0x300,(int *)0,&line);
  228.         line>>=8;
  229.         if (oldline==line)
  230.             return line+1;
  231.         oldline=line;    
  232.     }
  233. }
  234.  
  235. /* the REAL bios interface -- used internally only. */
  236.  
  237. static void video(ax, cx, dx)
  238.     int ax, *cx, *dx;
  239. {
  240.     union REGS regs;
  241.  
  242.     regs.x.ax=ax;
  243.     if ((ax&0xff00)==0x600 || (ax&0xff00)==0x700)
  244.         regs.h.bh=attr[screen][vmode];
  245.     else
  246.     {
  247.         regs.h.bh=0;
  248.         regs.h.bl=attr[screen][vmode];
  249.     }
  250.     if (cx) regs.x.cx=*cx;
  251.     if (dx) regs.x.dx=*dx;
  252.     int86(0x10, ®s, ®s);
  253.     if (dx) *dx=regs.x.dx;
  254.     if (cx) *cx=regs.x.cx;
  255. }
  256.  
  257. /* The following function determines which character is used for
  258.  * commandline-options by command.com. This system call is undocumented
  259.  * and valid for versions < 4.00 only.
  260.  */
  261.  
  262. int switchar()
  263. {
  264.     union REGS regs;
  265.     regs.x.ax=0x3700;
  266.     int86(0x21, ®s, ®s);
  267.     return regs.h.dl;
  268. }
  269.  
  270. #endif
  271.